#pragma once

#include <vector>
#include <algorithm>

#include "node.h"

namespace PBVP {
	class ContourTree;
	class AugmentedContourTree;
	/*! \brief A class for constructing contour trees from volume data
	*
	* An abstract class that is to be implemented by real 2D/3D volumetric data
	*/
	class ConTreeConstructor {
	public:
		/// default constructor
		ConTreeConstructor(void); 

		/// Destructor
		virtual ~ConTreeConstructor(void); 

		/// Compute Contour Tree without topo info on edges
		virtual ContourTree* getContourTree();

		/// Compute Contour Tree Augmented with topo info
		virtual AugmentedContourTree* getAugmentedContourTree();

	protected:
		/// list of critical points
		std::vector<CriticalPoint>* m_pCPVector;

		/// Construct the join tree
		virtual ContourTree* constructJoinTree(void);

		/// Construct the split tree
		virtual ContourTree* constructSplitTree(void);

		/// Calculate all critical points and put them in a sorted array
		virtual void calcSortedCriticalPoints();

		/// Get the Number of critical points
		virtual int getNumOfCPs() const = 0;

		/// Get the value of a critical point
		virtual float getCPValue(int id) const = 0;

		/// Check if a critical point is a minimum
		virtual bool isMinimum(const CriticalPoint& cp) = 0;
		/// Check if a critical point is a maximum
		virtual bool isMaximum(const CriticalPoint& cp) = 0;

		/// The the index of cells that neighboring a vertex
		virtual int getNeighbors(int vid, int* neighbors) = 0;

		/// Compute the list of critical points and their topological info
		virtual void calcLUStars() = 0;

		virtual int maxNeighborNumbers() const = 0;

		static const int MAX_NEI_NUM;
	};

}